package com.lenin.omena.server;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;

import com.lenin.omena.shared.domain.User;

//@Component
public abstract class JdoDAO<ID extends Serializable, T> {

	protected Class<T> entityClass;

	
	protected PersistenceManager pm = PMF.getPersistenceManager();
	
	
	public JdoDAO() {
		ParameterizedType genericSuperclass = (ParameterizedType) getClass()
				.getGenericSuperclass();
		this.entityClass = (Class<T>) genericSuperclass
				.getActualTypeArguments()[1];
	}
	
	
	public T findByKey(String key) {
		
		Query query = pm.newQuery(entityClass);
		query.setFilter("key == keyParam");
		query.declareParameters("String keyParam");
		
		List<T> resultList = (List<T>)query.execute(key);
		
		T entity = null;
		
		if(resultList.size() > 0) {
			entity = resultList.get(0);
		}
		
		
		return entity;
		
	}
	

	public List<T> findAll() {

		
		Query query = pm.newQuery(User.class);
		
		List<T> resultList = (List<T>) query.execute();
		
		
		return resultList;
		
	}

	
	public T persist(T entity) {
		
		T result = null;
		
		Transaction tx = pm.currentTransaction();
		
		
		try
		{
		    tx.begin(); // Start the PM transaction

		    result = pm.makePersistent(entity);

		    tx.commit(); // Commit the PM transaction
		}
		finally
		{
		    if (tx.isActive())
		    {
		        tx.rollback(); // Error occurred so rollback the PM transaction
		    }
		}
		
		
		return result;

	}
	
	
	public T remove(T entity) {
		
		Transaction tx = pm.currentTransaction();
		
		T result = null;
		
		try
		{
		    tx.begin(); // Start the PM transaction

		    pm.deletePersistent(entity);
		    
		    result = entity;
		    
		    tx.commit(); // Commit the PM transaction
		    
		}
		finally
		{
		    if (tx.isActive())
		    {
		        tx.rollback(); // Error occurred so rollback the PM transaction
		    }
		}
		
		return entity;

	}

	
	public T removeByKey(String key) {
		
		T result = null;
		
		T entity = findByKey(key);
		
		result = remove(entity);
		
		return result;
		
	}
	
	
	public T detachCopy(T entity) {
		
		T result = pm.detachCopy(entity);
		
		return result;
		
	}
	
	
	public List<T> detachCopy(List<T> list) {
		
		List<T> resultList = new ArrayList<T>(pm.detachCopyAll(list));
		
		return resultList;
		
	}
	

}
